#include "jsonurl.h"
#include "ui_jsonurl.h"

#include <QNetworkAccessManager>
#include <QMessageBox>
#include <QNetworkReply>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QStyleFactory>
#include <typeinfo>

JsonUrl::JsonUrl(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::JsonUrl)
{
    ui->setupUi(this);

    // 初始化treeWidget显示样式
    ui->treeWidget->clear(); // 清空数据
    ui->treeWidget->setHeaderHidden(true); // 是否隐藏表头
    ui->treeWidget->setStyle(QStyleFactory::create("windows")); // 加上虚线

    // 监听item单击事件
    connect(ui->treeWidget, &QTreeWidget::itemClicked, this, &JsonUrl::itemClicked);
}

JsonUrl::~JsonUrl()
{
    delete ui;
}

/**
 * @brief JsonUrl::on_pushButton_clicked
 * 获取JSON数据，并且用树状形式列出
 */
void JsonUrl::on_pushButton_clicked()
{
    ui->treeWidget->clear(); // 清空数据

    QString webUrl = ui->lineEdit->text().trimmed();

    getJson(webUrl);  // 获得json网址的数据
}

/**
 * 获得json对象
 * webUrl: json网址
 */
void JsonUrl::getJson(QString webUrl)
{
    QNetworkAccessManager *manager = new QNetworkAccessManager;
    QUrl url(webUrl);
    QNetworkRequest request(url);

    // 对数据进行解析
    QObject::connect(manager, &QNetworkAccessManager::finished, [this](QNetworkReply *reply) {
        if(reply->error()) {
            QMessageBox::information(NULL, "提示", reply->errorString());
        } else {
            // 将字符串转换为QJsonDocument
            QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll()); // QJsonDocument格式

            // 检查jsonDoc是否包含一个有效的JSON对象
            if (jsonDoc.isNull())
            {
                QJsonParseError err;
                qDebug() << err.errorString();
                QMessageBox::information(NULL, "提示", "不是有效的json对象");
                return -1;
            }

            qDebug() << jsonDoc << "\n"; // 输出 QJsonDocument

            this->checkObjOrArr(jsonDoc); // 判断QJsonDocument是对象还是数组

            // int nLen = rootObj.length(); // 对象长度
            // qDebug() << " nLen = " << nLen << "\n";qDebug() << " rootObj.keys() = " << rootObj.keys() << "\n"; // 对象的key
            // QList<QString> mykeys = rootObj.keys();
            // qDebug() << mykeys << "\n";
            // QByteArray request_json = jsonDoc.toJson( QJsonDocument::JsonFormat::Indented ); // 将QJsonDocument转换为Json
            // qDebug() << request_json << "\n";
            // return request_json; // 返回json数据
        }
        // 在当前对象的所有事件处理完成后再删除对象
        reply->deleteLater();
        reply = nullptr;
    });

    //向网页发起get请求
    manager->get(request);
}

/**
 * 判断QJsonDocument是对象还是数组
 */
void JsonUrl::checkObjOrArr(QJsonDocument jsonDoc)
{
    QTreeWidgetItem *current_item = new QTreeWidgetItem();
    ui->treeWidget->addTopLevelItem(current_item); // 添加顶层节点
    current_item->setExpanded(true); // 是否展开节点

    /**** QJsonDocument如果是对象，显示json树列表 ****/
    if(jsonDoc.isObject())
    {
        QJsonObject rootObj = jsonDoc.object(); // 将QJsonDocument转换为QJsonObject
        qDebug() << rootObj << "\n"; // QJsonObject

//        this->displayJsonTree(rootObj); // 显示json数据树

        current_item->setText(0, "根节点");
        current_item->setIcon(0,QIcon(QString(":/images/node.ico")));  // 设置父节点的图片

        this->AnalysisJsonObj(rootObj, current_item); // 分析json对象
    }

    /**** QJsonDocument如果是数组，显示json树列表 ****/
    if(jsonDoc.isArray())
    {
        current_item->setText(0, "[ ] 根节点");

        QJsonArray rootArray = jsonDoc.array(); // 将QJsonDocument转换为QJsonArray
        QJsonValue obj_value = rootArray;

        this->AnalysisJsonValue(obj_value, current_item);
    }
}

/**
* 添加顶层节点，显示json数据根节点名字
* rootObj： QJsonObject对象
*/
void JsonUrl::displayJsonTree(QJsonObject &rootObj)
{
    QTreeWidgetItem *current_item = new QTreeWidgetItem();

    ui->treeWidget->addTopLevelItem(current_item); // 添加顶层节点
    current_item->setExpanded(true); // 是否展开节点
    current_item->setText(0, "根节点");
    current_item->setIcon(0,QIcon(QString(":/images/node.ico")));  // 设置父节点的图片

    this->AnalysisJsonObj(rootObj, current_item); // 分析json对象
}

/**
 * 添加节点
 * jsonObj: QJsonObject对象数据
 * root： 节点
 */
void JsonUrl::AnalysisJsonObj(QJsonObject &jsonObj, QTreeWidgetItem *root )
{
    QList<QString> mykeys = jsonObj.keys();  // 对象的全部key列表
    qDebug() << mykeys.length();

    for (int i = 0; i < mykeys.length(); ++i)
    {
        QString keyname = mykeys[i]; // 对应的key的值

        QTreeWidgetItem *current_item = new QTreeWidgetItem();
        if(root)
        {
            root->addChild(current_item);
            root->setIcon(0, QIcon(QString(":/images/node.ico")));  // 设置父节点的图片
        }

        QJsonValue obj_value = jsonObj.value(keyname);
        this->AnalysisJsonValue(obj_value, current_item);
        this->SetItem(current_item, keyname, obj_value);
    }
}

/**
 * 显示节点下的数据，迭代显示数据 (判断是否对象或者数组)
 * value： 键对应的值
 * root： 节点
 */
void JsonUrl::AnalysisJsonValue(QJsonValue &value, QTreeWidgetItem *root)
{
    if (value.isObject()) // 如果是对象
    {
        QJsonObject jsonObj = value.toObject();
        this->AnalysisJsonObj(jsonObj, root);
    }
    else if(value.isArray())  // 如果是数组
    {
        QJsonArray arr = value.toArray();

        for (int i = 0; i < arr.size(); ++ i)
        {
            QTreeWidgetItem * current_item = new QTreeWidgetItem();

            if(root)
            {
                root->addChild(current_item); // 添加数组节点
                root->setIcon(0, QIcon(QString(":/images/node.ico")));  // 设置父节点的图片（数组节点）
            }

            QString keyname = QString::number(i) + "]"; // key的名字 (数组节点)
            QJsonValue jv = arr[i]; // key的值

            this->SetItem(current_item, keyname, jv);

            AnalysisJsonValue(jv, current_item); // 迭代节点上的数据（对象或数组，显示格式QList）
        }
    }
    else if (value.isString())
    {
    }
    else if (value.isDouble())
    {
    }
}

/**
 * 显示节点 键值对数据 （在key后添加value）
 * item: 节点
 * keyname: key名
 * value: key对应的值
 */
void JsonUrl::SetItem(QTreeWidgetItem *item, QString &keyname, QJsonValue &value)
{
    QString text = keyname; // key的名

    if (value.isObject()) // 对象
    {
        text.prepend("[");  // {}
    }
    else if (value.isArray()) // 数组
    {
        text.prepend("[ ] ");
    }
    else if(value.isString())
    {        
        QString value_str = value.toString();
        text.append( " : " );
        text.append(value_str); // 显示字符串键值
    }
    else if(value.isDouble())
    {
        double double_value = value.toDouble();
        text.append(" : ");
        text.append(QString::number(double_value)); // 显示数字键值
    }

    item->setExpanded(true); // 节点展开
//    item->setIcon(0,QIcon(QString(":/images/item.png")));  // 设置最终节点的图片
    item->setText(0, text); // 节点添加数据
}

/**
 * 发送json规则给父窗口
 */
void JsonUrl::on_pushButton_2_clicked()
{
    QString jsonUrl = ui->lineEdit_2->text().trimmed();

    emit sendJsonRule(jsonUrl); // 发送信号

    this->close();
}

//鼠标单击触发
void JsonUrl::itemClicked(QTreeWidgetItem *item, int column)
{
    qDebug() << "鼠标点击" << item->text(column) << column;

    ui->lineEdit_2->setText("sdf");
}
